package ui;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.JTextComponent;

import core.Utility;

public class WindowCommandBox extends JTextField implements DocumentListener,
KeyListener, Runnable
{
	/**
	 * 
	 */
	private static enum Mode {
		AUTOCOMPLETED, COMPLETION, ENTERED,ACTION
	}

	private Mode mode = Mode.AUTOCOMPLETED;
	private final List<String> words;
	private JTextComponent editor;

	//All sorted since binary search is used
	private final String[] SUPPORTED_COMMANDS = { "add","archive", "checkif", "delete", "done", "edit", "exit",
			"find", "full", "help","hide", "login", "overdue", "postpone", "reminder", "search", "tutorial", "undo"};
	private final String[] POPUP_COMMANDS = {"archive", "done", "checkif", "delete","find","edit", "overdue", "postpone", "reminder", "search"};
	private static final String[] DIALOG_COMMANDS = {"archive", "done", "find", "overdue", "reminder"};

	private int autoCompletePos;
	private String autoCompleteString;
	private String userCommand;

	private boolean newEditPostpone = true;

	public WindowCommandBox() {

		this.setEditable(true);

		editor = this;
		editor.getDocument().addDocumentListener(this);
		editor.addKeyListener(this);

		editor.setFocusTraversalKeysEnabled(false);
		
		words = new ArrayList<String>();
		for (String command : SUPPORTED_COMMANDS) {
			words.add(command);
		}
	}

	@Override
	public void changedUpdate(DocumentEvent e) {
	}

	@Override
	public void insertUpdate(DocumentEvent ev) {
		if (ev.getLength() != 1) {
			return;
		}

		int changeLocation = ev.getOffset();
		String userCommand = null;
		userCommand = editor.getText();// (0, changeLocation + 1);

		// Return if not beginning of the string
		if (userCommand.indexOf(" ") != -1) {
			return;
		}
		String prefix = userCommand.toLowerCase();

		for (String command : SUPPORTED_COMMANDS) {
			if (command.startsWith(prefix)) {
				this.autoCompleteString = command.substring(prefix.length());
				this.autoCompletePos = changeLocation + 1;
				SwingUtilities.invokeLater(this);
				break;
			}
		}
	}

	private void insertText(JTextComponent editor, String textToInsert, int pos) {
		String currText = editor.getText();
		if (textToInsert == null || pos < 0) {
			return;
		}
		editor.setText(currText.substring(0, pos) + textToInsert
				+ currText.substring(pos, currText.length()));
	}

	@Override
	public void removeUpdate(DocumentEvent e) {
	}

	public void keyPressed(KeyEvent userKeyPressed) {
		
		if (userKeyPressed.getKeyCode() == KeyEvent.VK_ENTER) {
			if (mode == Mode.COMPLETION && !(editor.getSelectedText() == null)) {
				int pos = editor.getSelectionEnd();
				insertText(editor, " ", pos);
				editor.setCaretPosition(pos + 1);
				mode = Mode.AUTOCOMPLETED;
			} 
			else{
				// (mode == Mode.ENTERED || mode == Mode.AUTOCOMPLETED) {
				userCommand = editor.getText();
				// System.out.println("Will execute command" + userCommand);
//				editor.setText("");
				mode = Mode.AUTOCOMPLETED;
				String userCommandHead = Utility.getHead(userCommand);
				if(userCommand.startsWith("login")) {
					firePropertyChange("showPasswordDialog",null,userCommand);
				}
				else if(userCommand.startsWith("help"))  {
					
					firePropertyChange("ShowHelp",null,userCommand);
				}
				else if(userCommand.startsWith("delete")) {
					firePropertyChange("deleteCommand", userCommandHead, userCommand);
				} else if((userCommand.startsWith("edit ") || userCommand.startsWith("postpone ")) && newEditPostpone) {
					firePropertyChange("autocompletevent", null, userCommand);
					mode = Mode.AUTOCOMPLETED;
					newEditPostpone = false;
				} else if(Arrays.binarySearch(DIALOG_COMMANDS,userCommandHead) >= 0) {
					firePropertyChange("showDialog",null,userCommand);
				}
				else if(userCommand.startsWith("show ")) {
					firePropertyChange("increaseSize",null,userCommand);
				}
			     else {
					firePropertyChange("userCommand",null,userCommand);
					if (userCommand.startsWith("edit") || userCommand.startsWith("postpone ")) {
						newEditPostpone = true;
					}
				}
			}
//		} else if (userKeyPressed.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
//			keyReleased(userKeyPressed);
		} else if(userKeyPressed.getKeyCode() == KeyEvent.VK_DELETE) {
			firePropertyChange("deleteCommand", null, "delete");
		}
	}
	@Override
	public void keyTyped(KeyEvent e) {
	}

	@Override
	public void keyReleased(KeyEvent e) {
		userCommand = editor.getText();
		
		if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_TAB || 
				(((e.getModifiers() & KeyEvent.CTRL_MASK) != 0) && (e.getKeyCode() == KeyEvent.VK_S 
				|| e.getKeyCode() == KeyEvent.VK_T || e.getKeyCode() == KeyEvent.VK_D))) {
			e.consume();
			return;
		}
		
		else if ("".equals(userCommand)) {
			firePropertyChange("clearView", null, userCommand);			
		}
		
		for (String command : POPUP_COMMANDS) {
			//Only keyword, hide all boxes
			
			if (userCommand.equals(command)) {
				firePropertyChange("clearView", null, userCommand);
			} else if (Utility.getHead(userCommand).equals(command)) {
				if (newEditPostpone) {
					firePropertyChange("userCommand", null, userCommand);
				}
			}
		}
	}

	public void enableEditingMode() {
		
	}
	
	@Override
	public void run() {
		autoComplete();
	}

	private void autoComplete() {
		String completeString = this.autoCompleteString;
		int completePos = this.autoCompletePos;
		insertText(editor, completeString, completePos);
		editor.setCaretPosition(completePos + completeString.length());
		editor.moveCaretPosition(completePos);
		mode = Mode.COMPLETION;
	}

	public String getUserCommand() {
		return userCommand;
	}
}
